﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SweetSurvey.Models;
using SweetSurvey.Models.Repositories;

namespace SweetSurvey.Tests.RepositoryTests
{
    /// <summary>
    ///This is a test class for OptionRepositoryTest and is intended
    ///to contain all OptionRepositoryTest Unit Tests
    ///</summary>
    [TestClass()]
    public class OptionRepositoryTest : RepositoryTestBase
    {
        #region Create Sample Data

        public static string CreateSampleOption(string questionId = null, short index = 0)
        {
            if (string.IsNullOrEmpty(questionId))
                questionId = QuestionRepositoryTest.CreateSampleQuestion();

            return (new OptionRepository()).Create(new Option()
            {
                QuestionId = questionId,
                Text = "Sample Option",
                Index = index
            });
        }

        public static IList<string> CreateSampleOptions(string questionId, short count = 10)
        {
            List<string> ids = new List<string>();
            for (short i = 0; i < count; i++)
            {
                ids.Add(CreateSampleOption(questionId, i));
            }
            return ids;
        }

        #endregion

        /// <summary>
        ///A test for Create
        ///</summary>
        [TestMethod]
        public void CreateTest()
        {
            // act
            var id = CreateSampleOption();

            // assert
            var entity = (new OptionRepository()).Get(id);
            Assert.IsNotNull(entity);
            Assert.IsFalse(string.IsNullOrEmpty(entity.Text));
        }

        /// <summary>
        ///A test for CreateOptionsByQuestionId
        ///</summary>
        [TestMethod]
        public void CreateOptionsByQuestionIdTest()
        {
            // prepare
            var questionId = QuestionRepositoryTest.CreateSampleQuestion();
            var options = new List<string>();
            options.Add("Red");
            options.Add("Green");
            options.Add("Purple");
            var repository = new OptionRepository();

            // act
            repository.CreateOptionsByQuestionId(questionId, options);

            // assert
            var ids = repository.GetOptionsByQuestionId(questionId).ToList();
            Assert.AreEqual<string>("Red", ids[0].Text);
            Assert.AreEqual<string>("Green", ids[1].Text);
            Assert.AreEqual<string>("Purple", ids[2].Text);
        }

        /// <summary>
        ///A test for Delete
        ///</summary>
        [TestMethod]
        public void DeleteTest()
        {
            // prepare
            var id = CreateSampleOption();
            var repository = new OptionRepository();

            // act
            repository.Delete(id);

            // assert
            try { repository.Get(id); Assert.Fail(); }
            catch (Exception) { }
        }

        /// <summary>
        ///A test for DeleteOptionsByQuestionId
        ///</summary>
        [TestMethod]
        public void DeleteOptionsByQuestionIdTest()
        {
            // prepare
            var questionId = QuestionRepositoryTest.CreateSampleQuestion();
            var ids = CreateSampleOptions(questionId);
            var repository = new OptionRepository();

            // act
            repository.DeleteOptionsByQuestionId(questionId);

            // assert
            Assert.IsTrue(ids.All(id =>
            {
                try { repository.Get(id); return false; }
                catch (Exception) { return true; }
            }));
        }

        /// <summary>
        ///A test for Get
        ///</summary>
        [TestMethod]
        public void GetTest()
        {
            // prepare
            var id = CreateSampleOption();
            var repository = new OptionRepository();

            // act
            var option = repository.Get(id);

            // assert
            Assert.IsNotNull(option);
            Assert.IsFalse(string.IsNullOrEmpty(option.Text));
        }

        /// <summary>
        ///A test for Update
        ///</summary>
        [TestMethod]
        public void UpdateTest()
        {
            // variables
            var newText = "Updated Text";

            // prepare
            var id = CreateSampleOption();
            var repository = new OptionRepository();
            
            // act
            var option = repository.Get(id);
            option.Text = newText;
            repository.Update(option);

            // assert
            Assert.AreEqual<string>(newText, repository.Get(id).Text);
        }
    }
}
